package com.ymk;

import com.alibaba.fastjson.JSON;
import com.ymk.base.cmd.ACmd;
import com.ymk.base.cmd.CmdSign;
import com.ymk.base.exception.MallException;
import com.ymk.base.utlis.ParamsBuilder;
import com.ymk.bo.mch.MchBO;
import com.ymk.bo.member.MemberBO;
import com.ymk.core.code.cmd.MemberCmdCode;
import com.ymk.core.code.cmd.SessionCmdCode;
import com.ymk.core.constants.MemberConstants;
import com.ymk.core.constants.SysConstants;
import com.ymk.core.constants.WxConstants;
import com.ymk.core.enums.mch.MchStatusEnum;
import com.ymk.core.enums.member.MemberStatusEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 小程序登录信息
 */
@Service
public class StoreSessionPostCmd extends ACmd {

    @Override
    public CmdSign executeStore(HttpServletRequest request, CmdSign sign) throws Exception {
        CmdSign respSign = new CmdSign(sign);
        MemberBO reqData = super.getData(sign, MemberBO.class);
        String openId = request.getHeader(WxConstants.X_WX_OPENID);

        String userData = this.redisTemplate.opsForValue().get(SysConstants.REDIS_KEY_JWT + openId);
        if (StringUtils.isNotBlank(userData)) {
            respSign.setSource(super.getSource(JSON.parseObject(userData, MemberBO.class)));
            return respSign;
        }

        ParamsBuilder paramsBuilder = ParamsBuilder.newBuild()
                .addParam("mchId", sign.getMchId())
                .addParam("wxOpenId", openId);
        CmdSign memberGetCmd = CmdSign.Builder.newBuild(sign)
                .setCmdCode(MemberCmdCode.MEMBER_GET)
                .setSource(paramsBuilder.build())
                .setScope(SysConstants.CMD_SERVER_SCOPE)
                .build();
        MemberBO dbMemberBO = this.scheduler.schedule(request, memberGetCmd, MemberBO.class);

        if (Objects.isNull(dbMemberBO)) {
            // 注册会员信息
            MemberBO memberBO = new MemberBO();
            memberBO.setWxOpenId(openId);
            memberBO.setName(MemberConstants.MEMBER_DEFAULT_NAME);
            memberBO.setMobile("");
            memberBO.setAvatarUrl("");
            memberBO.setStatus(MemberStatusEnum.NORMAL.getStatus());
            memberBO.setMchId(sign.getMchId());
            super.setCreatedData(sign, memberBO);
            super.setModifiedData(sign, memberBO);
            CmdSign memberPostCmd = CmdSign.Builder.newBuild(sign)
                    .setCmdCode(MemberCmdCode.MEMBER_POST)
                    .setSource(memberBO)
                    .setScope(SysConstants.CMD_SERVER_SCOPE)
                    .build();
            CmdSign cmdSign = this.scheduler.schedule(request, memberPostCmd);
            dbMemberBO = super.getData(cmdSign, MemberBO.class);
        }

        this.redisTemplate.opsForValue().set(SysConstants.REDIS_KEY_JWT + openId, JSON.toJSONString(dbMemberBO), 6, TimeUnit.HOURS);
        respSign.setSource(super.getSource(dbMemberBO));
        return respSign;
    }

    @Override
    public CmdSign verify(HttpServletRequest request, CmdSign sign) throws Exception {
        String openId = request.getHeader("X-WX-OPENID");

        if (StringUtils.isBlank(openId)) {
            throw new MallException("请求异常,header未发现openID");
        }

        if (Objects.isNull(sign.getMchId())) {
            throw new MallException("商户id为空");
        }

        MchBO mch = this.schedulerFacade.getMch(request, sign.getMchId());
        if (Objects.isNull(mch) && Objects.isNull(mch.getId())) {
            throw new MallException("商户不存在");
        }

        if (!MchStatusEnum.NORMAL.getStatus().equals(mch.getStatus())) {
            throw new MallException("商户异常");
        }
        return null;
    }

    @Override
    public boolean anon(CmdSign sign) {
        return true;
    }

    @Override
    public String getCmdCode() {
        return SessionCmdCode.STORE_MEMBER_POST;
    }

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
}
